package com.sky.wsp.sql.scanner.utils;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;

import java.io.File;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.*;

/**
 * @author wangshaopeng@talkweb.com.cn
 * @desccription 在此输入描述
 * @date 2024/11/14
 */
public class MyFileUtil {

    /**
     * 列出目录下所有jar/war/tar
     */
    public static File[] listPackFiles(String path) {
        File dir = new File(path);
        if (!dir.exists()) {
            return null;
        }
        if (dir.isFile()) {
            return new File[]{dir};
        }
        File[] files = dir.listFiles();
        if (files == null || files.length == 0) {
            return null;
        }
        List<File> fileList = new ArrayList<>();
        for (File file : files) {
            if (file.isFile() && (file.getName().endsWith(".jar") || file.getName().endsWith(".war") || file.getName().endsWith(".tar"))) {
                fileList.add(file);
            }
        }
        return fileList.toArray(new File[fileList.size()]);
    }

    /**
     * 根据jar/war/tar包的全路径，生成解压路径，例如：
     * D:\tmp\cloud-rbac.war ==> D:\tmp\cloud-rbac
     * D:\tmp\ctserver.jar ==> D:\tmp\ctserver
     * <p>
     * 如果是目录，则原样返回
     * D:\tmp\ctserver ==> D:\tmp\ctserver
     */
    public static File unPackageDir(File file) {
        if (file.isDirectory()) {
            return file;
        }
        String fileName = file.getName();
        fileName = fileName.substring(0, fileName.lastIndexOf("."));
        File outputFile = new File(file.getParent(), fileName);
        if (!outputFile.exists()) {
            outputFile.mkdirs();
        }
        return outputFile;
    }


    public static void findByName(File unZipDir, Map<String, File> map) {
        if (map.size() == 2) {
            return;
        }
        File[] files = unZipDir.listFiles();
        if (null == files) {
            return;
        }
        for (File file : files) {
            if (map.size() == 2) {
                return;
            }
            String name = file.getName();
            if (file.isDirectory()) {
                if (name.equals("classes")) {
                    map.put("classes", file);
                    continue;
                }
                if (name.equals("lib")) {
                    map.put("lib", file);
                    continue;
                }
                findByName(file, map);
            }
        }
    }

    public static void decompileLibJar(File libDir, JdUtil jdUtil, File sourceDir, List<String> logs) {
        File[] files = libDir.listFiles();
        if (null == files) {
            return;
        }
        for (File jarDir : files) {
            if (jarDir.isDirectory()) {
                File jarSourceDir = new File(sourceDir, jarDir.getName());
                String jarPath = jarDir.getAbsolutePath();
                int libPathLength = jarPath.length() + 1;
                decompileClasses(jarDir, libPathLength, jdUtil, jarSourceDir);
                logs.add("libJar反编译完成：" + sourceDir.getAbsolutePath() + File.separator + jarDir.getName());
            }
        }
    }

    public static void decompileClasses(File classesPath, int baseLength, JdUtil jdUtil, File sourceDir) {
        File[] files = classesPath.listFiles();
        if (null == files) {
            return;
        }
        for (File file : files) {
            String name = file.getName();
            if (file.isDirectory()) {
                decompileClasses(file, baseLength, jdUtil, sourceDir);
            } else {
                if (name.endsWith(".class")) {
                    String clazzPath = file.getAbsolutePath();
                    String packageName = clazzPath.substring(baseLength);
                    String s = jdUtil.readFile(packageName);
                    if (null == s) {
                        continue;
                    }
                    String javaName = packageName.substring(0, packageName.lastIndexOf('.')) + ".java";
                    File sourceJava = new File(sourceDir, javaName);
                    FileUtil.writeString(s, sourceJava, Charset.defaultCharset());
                    System.out.println("反编译成功：" + sourceJava.getAbsolutePath());
                }
            }
        }
    }

    /**
     * 优先在项目根路径（jar包所在文件夹）下查找，未找到则在classPath（jar包里面）进行查找
     */
    public static File findFileInProject(String simpleFileName) {
        // 项目路径下配置文件有限
        File file = new File(simpleFileName);
        if (file.exists()) {
            System.out.println("MyFileUtil.findFileInProject: " + file.getAbsolutePath());
            return file;
        }
        // 项目路径下找不到，到classPath路径下找
        URL resource = HutoolCompressUtil.class.getResource("/" + simpleFileName);
        if (null == resource) {
            System.err.println("项目路径下或类路径下未找到：" + simpleFileName);
            return null;
        }
        file = new File(resource.getFile());
        if (file.exists()) {
            System.out.println("MyFileUtil.findFileInProject: " + file.getAbsolutePath());
            return file;
        }
        System.err.println("未找到" + simpleFileName + "：" + file.getAbsolutePath());
        return null;
    }

    /**
     * 忽略名单
     */
    public static Set<String> getLinesAsSet(String simpleFileName) {
        File file = findFileInProject(simpleFileName);
        List<String> lines = FileUtil.readLines(file, CharsetUtil.CHARSET_UTF_8);
        Set<String> contentLines = new HashSet<>();
        for (String line : lines) {
            line = line.trim();
            if (StrUtil.isBlank(line) || line.startsWith("#")) {
                continue;
            }
            contentLines.add(line);
        }
        return contentLines;
    }
}
